#include <iostream>
#include <stdlib.h>


enum difficulty{
	EASY = 25, NORMAL = 50, HARD = 100
};

//declare functions
void story();
difficulty setDifficulty();

int getNumber(void);
int guessNumber(int randomNumber);
int enterNumber(void);
int cpuGuess(int userNumber);
void results(int numberOfGuesses,int numberOfCPUGuesses);

//global variables
difficulty myDifficulty; // declaring a value of type difficulty. (can only store EASY, NORMAL or HARD) Is NOT an int. An int can store 4 billion values, a difficulty can store 3 here.

int main(void)
{
	story();

	myDifficulty = setDifficulty();

	////////////////////////////////////////////////////////////////////////
	////////////////////////         main loop.  ///////////////////////////
	////////////////////////////////////////////////////////////////////////
	
	while(true)
	{
		int randomNumber;
		randomNumber = getNumber();

		int numberOfGuesses;
		numberOfGuesses = guessNumber(randomNumber);

		int userNumber;
		userNumber = enterNumber();

		int numberOfCPUGuesses;
		numberOfCPUGuesses = cpuGuess(userNumber);

		results(numberOfGuesses,numberOfCPUGuesses);
	}

	////////////////////////////////////////////////////////////////////////
	////////////////     end of main loop      /////////////////////////////
	////////////////////////////////////////////////////////////////////////

	return(0);
}

void story(void)
{
    std::cout << "Welcome to my game." << std::endl;
	std::cout << "In this game you will pit your wits against the CPU of your computer, you will have to try and guess the number that the computer is thinking of and it will do the same for you. Whoever manages to win with the least guesses is the winner! Repeat untill you are bored." << std::endl;
}

difficulty setDifficulty(void)
{
    int choice;
    std::cout << "Please select your difficulty:" << std::endl;
    std::cout << "1: Easy" << std::endl;
    std::cout << "2: Normal" << std::endl;
    std::cout << "3: Hard" << std::endl;

    std::cout << "Enter your choice :";
    std::cin >> choice;

    switch(choice)
    {
	case 1:
	     return EASY;
	case 2:
	     return NORMAL;
	case 3:
	     return HARD;
	default:
		std::cout << "Since you can't choose correctly ill pick Normal for you." << std::endl;
		return NORMAL;
    };
}

int getNumber(void)
{
	int randomNumber;
	randomNumber = (rand()%myDifficulty) - 1;
	
	return randomNumber;
}

int guessNumber(int randomNumber)
{
	int numberOfGuesses = 0;
	int currentGuess;
	
	bool incorrect = true;

	while(incorrect)
	{
		numberOfGuesses++;

guess:

		std::cout << "Please enter a number between 1 and " << myDifficulty << ": ";
		std::cin >> currentGuess;
		std::cout << std::endl;

		if(currentGuess > myDifficulty || currentGuess < 1)
		{
			std::cout << "That is an illegal guess..." << std::endl;
			numberOfGuesses--; //take a guess away as they have wasted the turn
			goto guess;
		}
		
		if(currentGuess == randomNumber)
		{
			std::cout << "Congratz! the number i was thinking was indeed " << randomNumber << "." << std::endl;
			incorrect = false;
		}

		if(currentGuess > randomNumber)
			std::cout << "Too Big! Try again" << std::endl;

		if(currentGuess < randomNumber)
			std::cout << "Too Small! Try again" << std::endl;

	}

	std::cout << "You did it in " << numberOfGuesses << " guesses." << std::endl;

	return numberOfGuesses;
}

int enterNumber(void)
{
	int userNumber;

	std::cout << "Please enter a number for the computer to guess between 1 and " << myDifficulty << ": ";
	std::cin >> userNumber;

	return userNumber;
}

int cpuGuess(int userNumber)
{
	int numberOfCPUGuesses = 0;
	bool incorrect = true;

	// initialises the highest guess to be equal to the highest possible value for the chosen difficulty.
	int highestGuess = myDifficulty;
	int lowestGuess = 1;
	int currentGuess = 0;

	while(incorrect)
	{
		numberOfCPUGuesses++;
		
		currentGuess = rand()%(highestGuess - lowestGuess) + lowestGuess + 1;

		std::cout << "The computer guessed " << currentGuess << "which is ";


		if(currentGuess > userNumber)
		{
			std::cout << "too high!";
			highestGuess = currentGuess;
		}

		if(currentGuess < userNumber)
		{
			std::cout << "too low!";
			lowestGuess = currentGuess;
		}

		if(currentGuess == userNumber)
		{
			std::cout << "Correct!";
			break;
		}

		std::cout << std::endl;
	}

	std::cout << "The computer did it in " << numberOfCPUGuesses << " guesses." << std::endl << std::endl;

	return numberOfCPUGuesses;
}

void results(int numberOfGuesses,int numberOfCPUGuesses)
{
	if(numberOfGuesses > numberOfCPUGuesses)
		std::cout << "The computer wins :( try again." << std::endl;

	if(numberOfGuesses < numberOfCPUGuesses)
		std::cout << "You win. Yay!" << std::endl;

	if(numberOfGuesses == numberOfCPUGuesses)
		std::cout << "Its a draw. try again?" << std::endl;
}